﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include "GcmpModelInterface.h"
#include "IElement.h"
#include "GcmpApiDeclaration.h"


namespace gcmp
{
    class IElementShapeHandleBehavior;
    class CommandParameters;

    /// \brief 辅助对象
    class GCMP_MODEL_INTERFACE_EXPORT IElementShapeHandle : public IElement
    {
        DEFINE_CAST_DERIVED(gcmp::IElementShapeHandle, gcmp::IElement);
    public:
        /// \brief 创建辅助对象
        ///
        /// \param pBehavior 辅助对象的行为组件
        /// \param masterId 辅助对象绑定的Element的Id
        /// \param position 辅助对象的位置
        /// \param positionIndexInMasterElement 辅助对象的位置索引
        /// \return IElementShapeHandle* 辅助对象指针
        static IElementShapeHandle* Create(OwnerPtr<IElementShapeHandleBehavior> pBehavior, const ElementId& masterId,
            const Vector3d position = Vector3d(), int positionIndexInMasterElement = -1);

        virtual ~IElementShapeHandle() {};

        /// \brief 获得辅助对象所绑定的Element的Id
        ///
        /// \return ElementId 辅助对象所绑定的Element的Id
        virtual ElementId GetMasterId() const = 0;

        /// \brief 设置辅助对象所绑定的Element的Id
        ///
        /// \param id 辅助对象所绑定的Element的Id
        /// \return void
        virtual void SetMasterId(const ElementId& id) = 0;

        /// \brief 获得辅助对象是否可以沿着工作平面移动
        ///
        ///默认是false
        /// \return bool true表示可以沿着工作平面移动，false表示不可以
        virtual bool IsMoveAlongWorkplane() const = 0;

        /// \brief 设置辅助对象是否可以沿着工作平面移动
        ///
        ///如果设置为true，移动时辅助对象的位置会投影到工作平面上进行计算；如果设置成false，则不会投影
        /// \param bMoveAlongWorkplane true表示可以沿着工作平面移动，false表示不可以
        /// \return void
        virtual void SetMoveAlongWorkplane(bool bMoveAlongWorkplane) = 0;

        /// \brief 获得辅助对象的位置
        ///
        /// \return Vector3d 辅助对象位置
        virtual Vector3d GetPosition() const = 0;

        /// \brief 设置辅助对象的位置
        ///
        /// \param pos 辅助对象的位置
        /// \return void
        virtual void SetPosition(const Vector3d& pos) = 0;

        /// \brief 获得辅助对象的位置索引，通过该索引去该辅助对象绑定的Element中拿辅助对象的位置
        ///
        /// \return int 辅助对象的位置索引
        virtual int GetPositionIndexInMasterElement() const = 0;

        /// \brief 获得辅助对象的位置索引，通过该索引去该辅助对象绑定的Element中拿辅助对象的位置
        ///
        /// \param positionIndexInMasterElement 辅助对象的位置索引
        /// \return void
        virtual void SetPositionIndexInMasterElement(int positionIndexInMasterElement) = 0;

        /// \brief 获得辅助对象位置的RdId
        ///
        /// \return RegenDataId 辅助对象位置的RdId
        virtual RegenDataId GetPositionRdIdForBehavior() const = 0;

        /// \brief 获得辅助对象位置索引的RdId
        ///
        /// \param RegenDataId 辅助对象位置索引的RdId
        /// \return void
        virtual RegenDataId GetShapeHandlePositionIndexInMasterElementRdId() const = 0;

        /// \brief 获得辅助对象绑定对象的ElementId的RdId
        ///
        /// \return RegenDataId 辅助对象绑定对象的ElementId的RdId
        virtual RegenDataId GetMasterIdRdIdForBehavior() const = 0;

        /// \brief 获得辅助对象的行为组件，用于扩展辅助对象的行为
        ///
        /// \return IElementShapeHandleBehavior 辅助对象的行为组件指针
        virtual const IElementShapeHandleBehavior* GetElementShapeHandleBehavior() const = 0; 

        /// \brief 获得辅助对象的行为组件，用于扩展辅助对象的行为
        ///
        /// \return IElementShapeHandleBehavior 辅助对象的行为组件指针
        virtual IElementShapeHandleBehavior* GetElementShapeHandleBehavior() = 0;

        /// \brief 设置辅助对象的行为组件，用于扩展辅助对象的行为
        ///
        /// \param pBehavior 辅助对象的行为组件指针
        /// \return void
        virtual void SetElementShapeHandleBehavior(OwnerPtr<IElementShapeHandleBehavior> pBehavior) = 0;

        /// \brief 设置辅助对象的行为组件，用于扩展辅助对象的行为
        ///
        /// \param pBehavior 辅助对象的行为组件指针
        /// \param moduleGroupGuid 所在的专业
        /// \return 添加成功：true；添加失败：false
        virtual bool SetElementShapeHandleBehavior(OwnerPtr<IElementShapeHandleBehavior> pBehavior, const Guid& moduleGroupGuid) = 0;

        /// \brief 判断辅助对象移动的时候，其Master是否可以一起移动
        ///
        ///  构件级协同：如果一个构件没有编辑权限，不能通过夹点拉伸、移动该构件。
        ///
        /// \return bool true：可以一起移动；false：不可以一起移动
        virtual bool CanMasterElementToMove() const = 0;

    public:
        /// \brief 获取Implementation Uid
        ///
        /// \return UniIdentity 返回ImplementationUid
        static UniIdentity GetImplementationUid();      
      
    };
}
